import org.geotools.factory.CommonFactoryFinder;
import org.geotools.filter.text.ecql.ECQL;
import org.geotools.sld.bindings.SLD;
import org.geotools.sld.v1_1.SLDConfiguration;
import org.geotools.styling.Stroke;
import org.geotools.styling.*;
import org.geotools.xml.Encoder;
import org.geotools.xml.Parser;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory2;
import org.opengis.style.GraphicalSymbol;

import java.awt.*;
import java.io.*;
import java.net.URI;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author jlj
 * @Date 2020/12/2 17:05
 * @Description
 * @Modified
 */
public class CreateSLD3 {
    private static final Color Line_Color = Color.blue;
    private static final Color Fill_Color = Color.yellow;
    private static final float Opacity = 1.0f;//透明度
    private static final float Line_Width = 1.5f;
    private static final float Point_Size = 10.0f;

    public void testCreateSLD(String outPath){
        try{
            String urlPng="E:\\9.4ShowDatas\\voronoi.png";
            File pngTest=new File(urlPng);
            StyledLayerDescriptor sld=createTestPolygon(pngTest.toURI().toURL());
            Map<URI,String> parms=new HashMap<>();
//            parms.put("version","1.1.0");
            parms.put(new URI("http://www.opengis.net/sld"),"StyledLayerDescriptor");
            parms.put(new URI("http://www.opengis.net/se"),"se");
            parms.put(new URI("http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd"),"schemaLocation");
            parms.put(new URI("http://www.w3.org/2001/XMLSchema-instance"),"xsi");
            parms.put(new URI("http://www.opengis.net/ogc"),"ogc");
            SLDTransformer transformer=new SLDTransformer(parms);


            System.out.println(transformer.transform(sld));
        }catch (Exception error){
            System.out.println("执行出错" + error.getLocalizedMessage());
        }
    }

    private StyledLayerDescriptor createTestPolygon(URL url) {
        StyleBuilder sb = new StyleBuilder();
        StyleFactory styleFactory = sb.getStyleFactory();

        StyleFactory sf3= CommonFactoryFinder.getStyleFactory();
        StyledLayerDescriptor sld = styleFactory.createStyledLayerDescriptor();
        NamedLayer namedLayer = styleFactory.createNamedLayer();

        sld.addStyledLayer(namedLayer);

        Style style = styleFactory.createStyle();
        namedLayer.addStyle(style);

        List<FeatureTypeStyle> ftsList = style.featureTypeStyles();

        FeatureTypeStyle fts = styleFactory.createFeatureTypeStyle();

        ftsList.add(fts);

        Rule rule = styleFactory.createRule();

        fts.rules().add(rule);

        PolygonSymbolizer polygon = styleFactory.createPolygonSymbolizer();

        rule.symbolizers().add(polygon);

        Graphic graphicFill1 = createGraphic(url, styleFactory);
        Graphic graphicFill2 = createGraphic(url, styleFactory);
        Graphic graphicStroke = createGraphic(url, styleFactory);
        Fill fill = styleFactory.createFill(null, null, null, graphicFill1);

        polygon.setFill(fill);

        Stroke stroke =
                styleFactory.createStroke(
                        null, null, null, null, null, null, null, graphicFill2, graphicStroke);
        polygon.setStroke(stroke);

        return sld;
    }

    private Graphic createGraphic(URL url, StyleFactory styleFactory) {
        List<GraphicalSymbol> symbolList = new ArrayList<GraphicalSymbol>();
        ExternalGraphic externalGraphic = styleFactory.createExternalGraphic(url, "image/png");
        symbolList.add(externalGraphic);
        Graphic graphicFill = styleFactory.graphicFill(symbolList, null, null, null, null, null);
        return graphicFill;
    }

    public void createSLD_Polygon(String geometryPropName, String pathSLD) {
        System.out.println("执行了sld3方式生成");
        FilterFactory2 filterFactory2 = CommonFactoryFinder.getFilterFactory2();
        StyleFactory styleFactory= CommonFactoryFinder.getStyleFactory();
        FeatureTypeStyle fts=styleFactory.createFeatureTypeStyle();
        SLDTransformer sldTransformer = new SLDTransformer();
        try {
            //添加边线、填充，加入到FeatureTypeStyle下面(literal:字面意义的)
            Stroke stroke = styleFactory.createStroke(filterFactory2.literal(Line_Color),
                    filterFactory2.literal(Line_Width), filterFactory2.literal(Opacity));
            Fill fill = styleFactory.createFill(filterFactory2.literal(Fill_Color), filterFactory2.literal(Opacity));
            Symbolizer symbolizer = styleFactory.createPolygonSymbolizer(stroke, fill, geometryPropName);
            Rule rule = styleFactory.createRule();
            rule.setName("自定义面样式");
            rule.symbolizers().add(symbolizer);
            //添加过滤条件，可以通过它给WMS图片添加唯一值渲染,加入到相应的rule中
            Filter filter = ECQL.toFilter("Layer='A'");
            rule.setFilter(filter);
            //添加当前rule
            fts.rules().add(rule);
            //生成style，对应的UserStyle标签
            Style userStyle = styleFactory.createStyle();
            userStyle.setName("myStyle_Name_Polygon");
            userStyle.featureTypeStyles().add(fts);
            NamedLayer namedLayer=new NamedLayerImpl();
            namedLayer.addStyle(userStyle);
            //生成StyledLayerDescription，顶级sld的根节点
            SLDConfiguration sldConfig11=new SLDConfiguration();
//            Parser parser11=new Parser(sldConfig11);
            File fileSLD = new File(pathSLD);
//            InputStreamReader inputReader=new InputStreamReader(new FileInputStream(fileSLD),Charset.forName("UTF-8"));
            OutputStream out = new FileOutputStream(fileSLD);
            StyledLayerDescriptor sld = new StyledLayerDescriptorImpl();
            sld.addStyledLayer(namedLayer);
            //最后产生样式文件
            Encoder encoder11=new Encoder(sldConfig11);
            encoder11.encode(sld, SLD.STYLEDLAYERDESCRIPTOR,out);
            sldTransformer.transform(sld, out);
//            sldTransformer.setNamespaceDeclarationEnabled(false);
//            System.out.println("转换结果："+sldTransformer.transform(sld));
            out.flush();
            out.close();
            System.out.println("生成结果是：" + pathSLD);
        } catch (Exception error) {
            System.out.println("生成样式[*.sld]文件失败：" + error.getLocalizedMessage());
            error.printStackTrace();
        }
    }
}
